// 包名
package com.example.customprogressdemo;
// 模块引入
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.SweepShader;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;

public class CustomProgress extends Component implements Component.EstimateSizeListener, Component.DrawTask, Component.TouchEventListener {
    // 自定义的构造方法
    public CustomProgress(Context context) {
        super(context);
        // 设置尺寸计算监听对象
        setEstimateSizeListener(this);
        // 设置绘制任务对象
        addDrawTask(this);
        // 设置支持点击交互
        setClickable(true);
        // 添加用户交互处理接口的监听
        setTouchEventListener(this);
    }

    public CustomProgress(Context context, AttrSet attrSet) {
        super(context, attrSet);
        // 设置backCircleWidth属性
        if (attrSet.getAttr("back_circle_width").isPresent()) {
            backCircleWidth = attrSet.getAttr("back_circle_width").get().getFloatValue();
        }
        // 设置scheduleCircleWidth属性
        if (attrSet.getAttr("schedule_circle_width").isPresent()) {
            scheduleCircleWidth = attrSet.getAttr("schedule_circle_width").get().getFloatValue();
        }
        // 设置progress属性
        if (attrSet.getAttr("progress").isPresent()) {
            progress = attrSet.getAttr("progress").get().getIntegerValue();
        }
        // 设置maxProgress属性
        if (attrSet.getAttr("max_progress").isPresent()) {
            maxProgress = attrSet.getAttr("max_progress").get().getIntegerValue();
        }
        // 设置textSize属性
        if (attrSet.getAttr("text_size").isPresent()) {
            textSize = attrSet.getAttr("text_size").get().getIntegerValue();
        }
        // 设置progressColor属性
        if (attrSet.getAttr("progress_color").isPresent()) {
            progressColor = attrSet.getAttr("progress_color").get().getColorValue();
        }
        // 设置title属性
        if (attrSet.getAttr("title").isPresent()) {
            title = attrSet.getAttr("title").get().getStringValue();
        }

        // 设置尺寸计算监听对象
        setEstimateSizeListener(this);
        // 设置绘制任务对象
        addDrawTask(this);

        // 设置支持点击交互
        setClickable(true);
        // 添加用户交互处理接口的监听
        setTouchEventListener(this);
    }

    // 此方法是EstimateSizeListener接口中的方法，实现它用来确定组件的尺寸
    @Override
    public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) {
        // 根据配置获取宽高
        int width = Component.EstimateSpec.getSize(widthEstimateConfig);
        int height = Component.EstimateSpec.getSize(heightEstimateConfig);

        // 将获取到宽高设置给组件
        setEstimatedSize(
                Component.EstimateSpec.getChildSizeWithMode(width, width, Component.EstimateSpec.PRECISE),
                Component.EstimateSpec.getChildSizeWithMode(height, height, Component.EstimateSpec.PRECISE));
        // 尺寸改变后 对画笔进行初始化
        initPaint();
        return true;
    }

    // 背景圆环的宽度，默认10
    public float backCircleWidth = 10f;
    // 进度圆环的宽度，默认16
    public float scheduleCircleWidth = 16f;
    // 当前进度
    public int progress = 50;
    // 总进度
    public int maxProgress = 100;
    // 文字的字号
    public int textSize = 50;
    // 进度圆环的颜色
    public Color progressColor = Color.GREEN;
    // 标题
    public String title = "进度";

    // 背景圆环的画笔实例
    private Paint backCirclePaint;
    // 进度圆环的画笔实例
    private Paint scheduleCirclePaint;
    // 文字的画笔实例
    private Paint textPaint;

    private void initPaint() {
        // 创建背景画笔
        backCirclePaint = new Paint();
        // 设置为描边风格
        backCirclePaint.setStyle(Paint.Style.STROKE_STYLE);
        // 设置端点圆角
        backCirclePaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
        // 设置抗锯齿和抗抖动
        backCirclePaint.setAntiAlias(true);
        backCirclePaint.setDither(true);
        // 设置描边宽度
        backCirclePaint.setStrokeWidth(backCircleWidth);
        // 设置描边颜色
        backCirclePaint.setColor(Color.LTGRAY);
        // 设置透明度
        backCirclePaint.setAlpha(0.3f);
        // 创建进度圆环画笔对象
        scheduleCirclePaint = new Paint();
        // 设置为描边风格
        scheduleCirclePaint.setStyle(Paint.Style.STROKE_STYLE);
        // 设置端点圆角
        scheduleCirclePaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
        // 设置抗锯齿和抗抖动
        scheduleCirclePaint.setAntiAlias(true);
        scheduleCirclePaint.setDither(true);
        // 设置描边宽度
        scheduleCirclePaint.setStrokeWidth(scheduleCircleWidth);
        scheduleCirclePaint.setColor(progressColor);


        // 文字画笔
        textPaint = new Paint();
        // 设置文字大小
        textPaint.setTextSize(textSize);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        // 获取组件的尺寸
        int width = getWidth();
        int height = getHeight();

        // 取宽高最小的为直径
        int diameter = Math.min(width, height);

        // 确定中心点
        Point centerPoint = new Point(width / 2f, height / 2f);
        int center = diameter / 2;
        // 半径，需要减去描边的宽度
        int radius = center - (int) (backCircleWidth);
        // 绘制背景圆环
        canvas.drawCircle(centerPoint, radius, backCirclePaint);

        // 圆环的外切矩形
        RectFloat rectFloat = new RectFloat(
                centerPoint.getPointX() - radius,
                centerPoint.getPointY() - radius,
                centerPoint.getPointX() + radius,
                centerPoint.getPointY() + radius);

        // 弧形进度
        float currentRadius = 360;
        if (progress > 0 && progress < maxProgress) {
            currentRadius = ((float)progress / maxProgress) * 360;
        }

        // 设置弧形的起始位置，默认x轴正方向为圆弧0度，我们需要调整到y轴正方向为0度，需要旋转270度
        Arc arc = new Arc(270, currentRadius, false);
        // 绘制弧形
        canvas.drawArc(rectFloat, arc, scheduleCirclePaint);

        // 计算文字长度
        float iLen = textPaint.measureText(progress + "点");
        float tLen = textPaint.measureText(title);
        // 设置文字起点左边，绘制文字
        canvas.drawText(textPaint, progress + "点", (float) width / 2 - iLen / 2, (float) height / 2 - textPaint.getTextSize() / 3f);
        canvas.drawText(textPaint, title, (float) width / 2 - tLen / 2, (float) height / 2 + textPaint.getTextSize());
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        switch (touchEvent.getAction()) {
            case TouchEvent.PRIMARY_POINT_UP:
               if (progress < maxProgress) {
                   progress += 1;
               }
                invalidate();
                break;
        }
        // 返回true表示处理此事件
        return true;
    }
}
